package com.hky.algorithm.realize;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Arrays;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Term {
    public int[] cards; // 看不见的牌的数量
    public int[] danger = new int[10]; // 计算出来的危险牌
    public Type type; // 牌的类型

    /**
     * 新建一种类型的牌，使用TypevalueOf(String type)给type赋值
     *
     * @param cards 牌
     * @param type  类型
     */
    public Term(int[] cards, String type) {
        this.type = Type.valueOf(type);
        this.cards = cards;
    }

    /**
     * 新建一种类型的牌，使用Type给type赋值
     *
     * @param cards 牌
     * @param type  类型
     */
    public Term(int[] cards, Type type) {
        this.type = type;
        this.cards = cards;
    }

    /**
     * 要胡的牌X和另外一张牌组成对子，所以X就是危险牌。统计完所有刻子和顺子后剩下的牌就都是危险牌了
     */
    public void addToDangerHuDui() {
        for (int i = 1; i < cards.length; i++) {
            if (cards[i] > 0) danger[i] = 1;
        }
    }

    /**
     * 要胡的牌X和另外两张牌组合成顺子或者刻子，把X加入到危险牌集合
     */
    public void addToDangerHuSunOrKe() {
        for (int i = 1; i < cards.length; i++) {
            if (cards[i] >= 2) danger[i] = 1; // 还差一张牌组成刻子
            // 还差一张牌组成顺子
            if (cards[i] >= 1 && i + 1 < cards.length && cards[i + 1] >= 1) {
                if (i - 1 >= 1) danger[i - 1] = 1;
                if (i + 2 < cards.length) danger[i + 2] = 1;
            }
            if (cards[i] >= 1 && i + 2 < cards.length && cards[i + 2] >= 1) danger[i + 1] = 1;
        }
    }

    /**
     * 从下标start开始获取刻子或者顺子
     *
     * @param start 开始位置
     * @return 刻子或者顺子，null代表没有获取到
     */
    public int[] getKe(int start) {
        int[] res = new int[3];
        for (int i = start; i < cards.length; i++) {
            if (cards[i] >= 3) { // 刻子
                cards[i] -= 3;
                Arrays.fill(res, i);
                return res;
            }
        }

        return null;
    }

    /**
     * 从下标start开始获取顺子
     *
     * @param start 开始位置
     * @return 刻子或者顺子，null代表没有获取到
     */
    public int[] getSun(int start) {
        int[] res = new int[3];
        for (int i = start; i + 2 < cards.length; i++) {
            if (cards[i] > 0 && cards[i + 1] > 0 && cards[i + 2] > 0) { // 顺子
                for (int j = 0; j < 3; j++) {
                    cards[i + j]--;
                    res[j] = i + j;
                }
                return res;
            }
        }

        return null;
    }

    /**
     * 从下标start开始获取对子，返回0代表获取失败
     *
     * @param start 开始位置
     * @return 对子的数字，返回0代表没有获取到
     */
    public int getDui(int start) {
        for (int i = start; i < cards.length; i++)
            if (cards[i] >= 2) {
                cards[i] -= 2;
                return i;
            }
        return 0;
    }

    /**
     * 回填对子
     *
     * @param dui 对子数字
     */
    public void fillBack(int dui) {
        if (dui == 0) return;
        cards[dui] += 2;
    }

    /**
     * 回填顺子或者刻子
     *
     * @param sunOrKe 顺子或则刻子
     */
    public void fillBack(int[] sunOrKe) {
        if (sunOrKe == null) return;
        for (int i : sunOrKe) cards[i]++;
    }

    public void printlnAllCards() {
        System.out.print("数字：" + type.name + " : |");
        for (int i = 1; i < 10; i++) {
            System.out.printf("%4d |", i);
        }
        System.out.println();

        System.out.print("原始：" + type.name + " : |");
        for (int i = 1; i < cards.length; i++) {
            System.out.printf("%4d |", cards[i]);
        }
        System.out.println();

        System.out.print("危险：" + type.name + " : |");
        for (int i = 1; i < danger.length; i++) {
            System.out.printf("%4d |", danger[i]);
        }

        System.out.println("\n");
    }
}
